package com.bbzn.device.client.controller;

import com.bbzn.device.client.vo.req.AuditVO;
import com.bbzn.device.client.aspect.OperationAnnotation;
import com.bbzn.device.client.constant.AuditConstant;
import com.bbzn.device.client.constant.DeviceConstant;
import com.bbzn.device.client.dataobject.*;
import com.bbzn.device.client.dto.audit.LeaveFormDTO;
import com.bbzn.device.client.dto.process.FlowDTO;
import com.bbzn.device.client.dto.process.ProcessFlowDTO;
import com.bbzn.device.client.exception.DefinitException;
import com.bbzn.device.client.service.*;
import com.bbzn.device.client.utils.*;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Author 黄志鹏
 * @Date 2021/3/16 17:11
 * @Version 1.0
 */

@RestController
@RequestMapping("/audit")
@Slf4j
@Api(value = "audit", tags = "审批管理 ")
@ApiSort(value = 1)// 大分类顺序
//@CrossOrigin
public class AuditController extends BaseApiService {

    @Autowired
    private CommonService commonService;

    @Autowired
    private SystemParamByCacheService systemParamByCacheService;

    @Autowired
    private RedisUtils<String> redisUtil;

    @Autowired
    private LeaveFormService leaveFormService;

    @Autowired
    private ProcessFlowService processFlowService;

    @Autowired
    private AuditNoticeService auditNoticeService;

    @Autowired
    private FlowNodeService flowNodeService;

    @Autowired
    private FlowService flowService;

    @Autowired
    private MiddleFlowNodeService middleFlowNodeService;

    /**
     * 查询请假单列表
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getLeaveFromList", method = RequestMethod.POST)
    @OperationAnnotation(content = "查询请假单列表")
    public BaseResponse getLeaveFromList(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        LeaveFormDTO leaveFormDTO = new LeaveFormDTO();
        leaveFormDTO.setPageNum(reqVO.getPageNum());
        leaveFormDTO.setPageSize(reqVO.getPageSize());
        if (null != reqVO.getPageNum()) {
            leaveFormDTO.setPageNum(reqVO.getPageNum());
        }
        if (null != reqVO.getPageSize()) {
            leaveFormDTO.setPageSize(reqVO.getPageSize());
        }
        if (null != reqVO.getImei()) {
            leaveFormDTO.setImei(reqVO.getImei());
        }
        leaveFormDTO.setStartIndex((reqVO.getPageNum() - 1) * reqVO.getPageSize());
        List<Long> ids = commonService.getUserIds(userId);
        leaveFormDTO.setIds(ids);
        PageInfo<LeaveForm> list = leaveFormService.selectPageBySelective(leaveFormDTO);
        return setResultSuccess(list);
    }


    /**
     * 查询请假审批结果详情
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getAuditNotice", method = RequestMethod.POST)
    @OperationAnnotation(content = "查询请假审批结果详情")
    public BaseResponse getAuditNotice(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        Map<String,Object> data = new HashMap();
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFormId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FORMID_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        ProcessFlow processFlow = new ProcessFlow();
        processFlow.setFormId(reqVO.getFormId());
        LeaveForm form = leaveFormService.selectByPrimaryKey(reqVO.getFormId());
        List<ProcessFlow> processFlows =  processFlowService.findByAll(processFlow);
        if(CollectionUtils.isEmpty(processFlows)){
            return setResultSuccess(null);
        }
        List<ProcessFlowDTO> dtoList = new ArrayList<>();
        for (ProcessFlow flow : processFlows) {
            ProcessFlowDTO dto = new ProcessFlowDTO();
            BeanUtils.copyProperties(flow,dto);
            AuditNotice notice = auditNoticeService.findOneByProcessFlowId(dto.getProcessId());
            dto.setAuditNotice(notice);
            if(userId.equals(flow.getOperatorId())){
                dto.setIsCurUserId(1);
            }else{
                dto.setIsCurUserId(0);
            }
            dtoList.add(dto);
        }
        if(CollectionUtils.isNotEmpty(dtoList)){
            dtoList.stream().sorted(Comparator.comparing(ProcessFlowDTO::getOperatorDeptname));
        }
        data.put("form",form);
        data.put("flows",dtoList);
        return setResultSuccess(data);
    }

    /**
     * 任务节点列表
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getFlow", method = RequestMethod.POST)
    @OperationAnnotation(content = "查询任务节点列表")
    public BaseResponse getFlow(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        FlowDTO flowDTO = new FlowDTO();
        flowDTO.setPageNum(reqVO.getPageNum());
        flowDTO.setPageSize(reqVO.getPageSize());
        if (null != reqVO.getPageNum()) {
            flowDTO.setPageNum(reqVO.getPageNum());
        }
        if (null != reqVO.getPageSize()) {
            flowDTO.setPageSize(reqVO.getPageSize());
        }
        flowDTO.setStartIndex((reqVO.getPageNum() - 1) * reqVO.getPageSize());
        List<Long> ids = commonService.getUserIds(userId);
        flowDTO.setIds(ids);
        PageInfo<Flow> list = flowService.selectPageBySelective(flowDTO);
        return setResultSuccess(list);
    }

    /**
     * 获取任务节点
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getFlowNode", method = RequestMethod.POST)
    @OperationAnnotation(content = "查询任获取任务节点详情")
    public BaseResponse getFlowNode(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFlewId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        FlowNode query = new FlowNode();
        query.setFlowId(reqVO.getFlewId());
        List<FlowNode> flowNodes = flowNodeService.findByAll(query);
        return setResultSuccess(flowNodes);
    }

    /**
     * 添加任务节点
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/addUptFlow", method = RequestMethod.POST)
    @OperationAnnotation(content = "添加任务节点")
    public BaseResponse addUptFlow(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFlewName()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_NAME_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (CollectionUtils.isEmpty(reqVO.getFlowNodes())) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (CollectionUtils.isEmpty(reqVO.getFlowNodes())) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }

        Flow flow  = new Flow();
        BeanUtils.copyProperties(reqVO,flow);
        String orderNo = OrderNoUtil.getOrderNo();
        if(null!=reqVO.getFlewId()){
            flow.setFlowId(reqVO.getFlewId());
        }
        flow.setUserId(userId);
        flow.setOrderNo(orderNo);
        flow.setFlowName(reqVO.getFlewName());
        flow.setCreateTime(new Date());
        if(null==flow.getFlowId()){
            flowService.insertSelective(flow);
        }else{
            flowService.updateByPrimaryKeySelective(flow);
        }
        flowNodeService.addFlopwNode(flow.getFlowId(),reqVO.getFlowNodes(),language);
        systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_ADD_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

    /**
     * 删除任务节点
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/delFlow", method = RequestMethod.POST)
    @OperationAnnotation(content = "删除任务节点")
    public BaseResponse delFlow(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFlewId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        ProcessFlow flow = new ProcessFlow();
        flow.setOrderNo(reqVO.getOrderNo());
        int count = processFlowService.findCountByAll(flow);
        if(count>0){
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_EXIST_PROCESS_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        flowService.deleteByPrimaryKey(reqVO.getFlewId());
        flowNodeService.deleteByFlowId(reqVO.getFlewId());
        systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_ADD_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }

    /**
     * 删除请假单
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/delLeaveForm", method = RequestMethod.POST)
    @OperationAnnotation(content = "删除请假单")
    public BaseResponse delLeaveForm(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFlewId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        ProcessFlow flow = new ProcessFlow();
        flow.setOrderNo(reqVO.getOrderNo());
        int count = processFlowService.findCountByAll(flow);
        if(count>0){
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_EXIST_PROCESS_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        leaveFormService.deleteByPrimaryKey(reqVO.getFormId());
        List<Long> ids = processFlowService.findIdByAll(flow);
        if(CollectionUtils.isNotEmpty(ids)){
            processFlowService.batchDel(ids);
        }
        systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_ADD_SUCCESS_PREFIX + language);
        return setResultSuccess(systemParam.getMassage());
    }




    /**
     * 创建请假单
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @OperationAnnotation(content = "创建请假单")
    public BaseResponse create(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception{
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getUserId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_CUS_ID_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getFlewId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FLEW_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getFlowNodeLevel()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_USERTYPE_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (reqVO.getUserId()==0 && reqVO.getFlowNodeLevel()==0) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_ZERO_CUS_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getReason()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_REASON_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getImei()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(DeviceConstant.DEVICE_ENUM, DeviceConstant.DEVICE_NO_IMEI_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getFormType()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FORMTYPE_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getStartTime()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_STARTTIME_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getEndTime()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_ENDTIME_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getAddress()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_ADDRESS_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        leaveFormService.createLeaveFrom(reqVO,userId,language);
        systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_CREATE_SUCCESS_PREFIX + language);
        return  setResultSuccess(systemParam.getMassage()) ;
    }

    /**
     * 审核请假单
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/auditFrom", method = RequestMethod.POST)
    @OperationAnnotation(content = "审核请假单")
    public BaseResponse auditFrom(@RequestBody AuditVO reqVO, HttpServletRequest request, HttpServletResponse response) throws Exception{
        SystemParam systemParam = null;
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        if (!OptionalBean.ofNullable(reqVO.getFormId()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_FORMID_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
//        if (!OptionalBean.ofNullable(reqVO.getUserId()).isPresent()) {
//            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_CUS_ID_PREFIX + language);
//            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
//        }
        if (!OptionalBean.ofNullable(reqVO.getFlowNodeLevel()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_USERTYPE_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getReason()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_REASON_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        if (!OptionalBean.ofNullable(reqVO.getResult()).isPresent()) {
            systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_NO_RESULT_PREFIX + language);
            throw new DefinitException(systemParam.getCode(), systemParam.getMassage());
        }
        leaveFormService.auditLeaveFrom(reqVO,userId,language);
        systemParam = systemParamByCacheService.getValues(AuditConstant.AUDIT_ENUM, AuditConstant.AUDIT_SUCCESS_PREFIX + language);
        return  setResultSuccess(systemParam.getMassage()) ;
    }

    /**
     * 获取节点等级
     *
     * @param reqVO
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/getFlowNodeLevel", method = RequestMethod.POST)
    @OperationAnnotation(content = "获取节点等级")
    public BaseResponse getFlowNodeLevel(@RequestBody AuditVO reqVO,HttpServletRequest request, HttpServletResponse response) throws Exception {
        SystemParam systemParam = null;
//        String secretKey = commonService.getAppSalt(request);
        String secretKey = commonService.getWebSalt(request);
        String language = MayiktJwtUtils.getLanguage(request, secretKey);
        Long userId = commonService.getUserId(request);
        FlowNode query = new FlowNode();
        query.setFlowNodeUserId(userId);
        query.setFlowId(reqVO.getFlewId());
        List<FlowNode> flowNodes = flowNodeService.findByAll(query);
        if(CollectionUtils.isEmpty(flowNodes)){
            return setResultSuccess(1);
        }
        return setResultSuccess(flowNodes.get(0).getFlowNodeLevel());
    }

}
